package com.tongjie.hotelbooking.controller.user;

import com.tongjie.hotelbooking.dto.CreateOrderRequest;
import com.tongjie.hotelbooking.dto.DtoConverters;
import com.tongjie.hotelbooking.dto.OrderDto;
import com.tongjie.hotelbooking.exception.BusinessException;
import com.tongjie.hotelbooking.http.BaseResponse;
import com.tongjie.hotelbooking.order.entity.Order;
import com.tongjie.hotelbooking.order.entity.OrderType;
import com.tongjie.hotelbooking.order.enums.OrderStatus;
import com.tongjie.hotelbooking.order.enums.SearchDirection;
import com.tongjie.hotelbooking.order.service.OrderService;
import com.tongjie.hotelbooking.sequence.service.SequenceService;
import com.tongjie.hotelbooking.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

@RestController
@RequestMapping("/user/order")
@Slf4j
public class UserOrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private SequenceService serialService;

    @PostMapping("/create")
    public BaseResponse<?> create(@RequestBody CreateOrderRequest request) {
        Date plannedCheckInDate = DateUtil.parseDate(request.getPlannedCheckInDate(), "yyyy-MM-dd");
        Date plannedCheckOutDate = DateUtil.parseDate(request.getPlannedCheckOutDate(), "yyyy-MM-dd");

        Date currentDate = DateUtils.truncate(new Date(), Calendar.DATE);

        this.validateCreateOrder(request, plannedCheckInDate, plannedCheckOutDate, currentDate);

        String orderNumber = this.serialService.nextOrderNumber();
        Order order = Order.builder()
                .orderNumber(orderNumber)
                .orderType(request.getOrderType())
                .region(StringUtils.join(request.getRegion(), ","))
                .hotelName(request.getHotelName())
                .plannedCheckInDate(plannedCheckInDate)
                .plannedCheckOutDate(plannedCheckOutDate)
                .dayCount(request.getDayCount())
                .singleRoomBudget(request.getSingleRoomBudget())
                .totalPeopleCount(request.getTotalPeopleCount())
                .kidCount(request.getKidCount())
                .additionalBudget(request.getAdditionalBudget())
                .roomInfos(request.getRoomInfos())
                .totalRoomCount(request.getTotalRoomCount())
                .needBreakfast(request.getNeedBreakfast())
                .noSmokingBreakfast(request.getNoSmoking())
                .needHotelInvoice(request.getNeedHotelInvoice())
                .arriveTime(DateUtil.parseDate(request.getArriveTime(), "HH:mm"))
                .totalBudget(request.getTotalBudget())
                .allowedHousemate(request.getAllowedHousemate())
                .build();
        this.orderService.createOrder(order);
        return BaseResponse.success();
    }

    private void validateCreateOrder(CreateOrderRequest request, Date plannedCheckInDate, Date plannedCheckOutDate, Date currentDate) {
        if (request.getOrderType() == null) {
            throw new BusinessException(1000, "请输入订单类型");
        } else if (request.getRegion() == null || request.getRegion().length == 0) {
            throw new BusinessException(1001, "请输入行政区域");
        } else if (StringUtils.isBlank(request.getHotelName())) {
            throw new BusinessException(1001, "请输入酒店名称");
        } else if (StringUtils.isBlank(request.getPlannedCheckInDate())) {
            throw new BusinessException(1002, "请输入入住日期");
        } else if (StringUtils.isBlank(request.getPlannedCheckOutDate())) {
            throw new BusinessException(1003, "请输入退房如期");
        } else if (plannedCheckInDate.before(currentDate)) {
            throw new BusinessException(1004, "入住日期不能早于当前日期");
        } else if (plannedCheckOutDate.before(plannedCheckInDate)) {
            throw new BusinessException(1005, "退房日期不能早于入住日期");
        } else if (request.getTotalBudget() == null || BigDecimal.ZERO.compareTo(request.getTotalBudget()) >= 0) {
            throw new BusinessException(1006, "请输入预算金额");
        } else if (request.getTotalRoomCount() == null || request.getTotalRoomCount() <= 0) {
            throw new BusinessException(1007, "请输入房间数量");
        } else if (request.getRoomInfos() == null) {
            throw new BusinessException(1008, "请输入房型");
        }

        if (OrderType.MULTI_ROOM.equals(request.getOrderType())) {
            if (request.getTotalPeopleCount() == null || request.getTotalPeopleCount() <= 0) {
                throw new BusinessException(1009, "请输入总人数");
            }
        }
    }


    @GetMapping("/find")
    public BaseResponse<Page<OrderDto>> findOrder(@RequestParam(required = false) OrderStatus orderStatus,
                                                  @RequestParam(required = false) Long lastId,
                                                  @RequestParam(required = false) SearchDirection searchDirection) {
        if (lastId != null && searchDirection == null) {
            return BaseResponse.fail("search direction cat not be null");
        }
        Page<OrderDto> result = this.orderService.findUserOrders(orderStatus, lastId, searchDirection).map(DtoConverters::orderDtoConverter);
        return BaseResponse.success(result);
    }

}
